package controller

import (
	"CampusCloudAid/dao/mysql"
	"CampusCloudAid/logic"
	"CampusCloudAid/models"
	"CampusCloudAid/pkg/jwt"
	"strconv"

	"github.com/go-playground/validator/v10"

	"fmt"
	"net/http"

	"go.uber.org/zap"

	"github.com/gin-gonic/gin/binding"

	"github.com/gin-gonic/gin"
)

// GetAllTasks
// @Summary 查询所有任务接口
// @Produce json
// @Description 查询所有任务接口
// @Tags 任务相关接口
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @router /api/v1/getAllTasks [get]
func GetAllTasks(ctx *gin.Context) {
	tasks, err := logic.GetAllTasks()
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if tasks == nil || len(tasks) == 0 {
		ResponseError(ctx, CodeNotTask)
		return
	}
	ResponseSuccess(ctx, tasks)
}

// GetTasksByConditional 按条件查询任务的函数
// @Summary 条件查询任务接口
// @Description 按条件查询任务的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamTasksByConditional true "注册参数"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/getTasksByConditional [post]
func GetTasksByConditional(ctx *gin.Context) {
	p := new(models.ParamTasksByConditional)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	tasks, err := logic.GetTasksByConditional(p)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, tasks)
}

// GetTaskInfo 查询任务详情的函数
// @Summary 查询任务详情接口
// @Description 查询任务详情的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamTaskInfo true "注册参数"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/getTaskInfo [post]
func GetTaskInfo(ctx *gin.Context) {
	p := new(models.ParamTaskInfo)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	task, err := logic.GetTask(int64(p.Id))
	if err != nil {
		ResponseError(ctx, CodeNotTask)
		return
	}
	ResponseSuccess(ctx, task)
}

// ReceiveTask 申领任务的函数
// @Summary 申领任务接口
// @Description 申领任务的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamReceiveTask true "注册参数"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/receiveTask [post]
func ReceiveTask(ctx *gin.Context) {
	//申领任务之前需要查询是否有该任务，该任务是否还没有被申领   根据id查询
	p := new(models.ParamReceiveTask)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	task, err := logic.GetTask(int64(p.Id))
	if err != nil {
		ResponseError(ctx, CodeNotTask)
		return
	}
	//判断任务是否已经被接单
	if task.TaskStatus != "发布" {
		ResponseError(ctx, CodeTaskNotReceive)
		return
	}

	//从token中获取userID
	userId, err := jwt.GetUserId(ctx)
	if err != nil {
		return
	}
	if userId == task.PublisherId {
		ResponseError(ctx, CodeReceiveFailed) //领取任务失败，因为是自己的任务；
		return
	}
	//任务表中修改申领人id，申领时间 即现在用户id ，需要获取现在正在登录的用户
	if err = logic.UpdateReceiveInfo(p.Id, userId); err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	//ctx.JSON(http.StatusOK, gin.H{
	//	"msg": "接单成功",
	//})
	ResponseSuccess(ctx, CodeSuccess)
}

// SubmitVoucherTask 提交凭证完成任务的函数
// @Summary 提交凭证完成任务接口
// @Description 提交凭证完成任务的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamSubmitVoucherTask true "注册参数"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/submitVoucherTask [post]
func SubmitVoucherTask(ctx *gin.Context) {
	//提交照片之前需要查询是否有该任务，根据id查询
	p := new(models.ParamSubmitVoucherTask)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	//任务表中修改凭证，任务状态，任务完成时间
	if err := logic.SubmitVoucherTask(p.Id, CompletionImage); err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "任务完成",
	})
}

//提交任务图片凭证+修改任务状态为已完成的接口；

// ImageAndSuccess 上传任务及提交任务；
// @Summary 上传任务完成图片
// @Description 上传任务完成图片，并将图片保存到服务器
// @Accept multipart/form-data
// @Param taskId formData int true "任务ID"
// @Param images formData file true "要上传的图片文件列表"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/task/imageAndSuccess [post]
func ImageAndSuccess(ctx *gin.Context) {
	// 获取任务ID
	taskIdStr := ctx.PostForm("taskId")
	taskId, err := strconv.ParseInt(taskIdStr, 10, 64)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": " task ID解析错误"})
		return
	}
	//userId, err := jwt.GetUserId(ctx)
	// 解析上传的多个文件
	files, err := ctx.MultipartForm()
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse files"})
		return
	}
	// 获取文件列表
	fileHeaders := files.File["images"]
	// 保存多个图片并获取路径
	imagePaths, err := logic.SaveCompletionImages(taskId, fileHeaders) // 保存到服务器并将图片变为json格式；
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save images"})
		return
	}
	if err = logic.UpdateTaskImage(taskId, imagePaths); err != nil { //
		zap.L().Error("更新任务凭证失败：", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	err = logic.InputTask(taskId)
	if err != nil {
		// 如果解析失败，返回错误信息给前端
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, string(imagePaths))
	// 返回成功响应，包含保存的图片路径
	//ctx.JSON(http.StatusOK, )
}

// ----------------------------------------------------
/*const CtxtUserIDKey = "publisher_id"

var ErrorUserNotLogin = errors.New("用户未登录")

func getCurrentUserID(c *gin.Context) (Uid int64, err error) {
	uid, ok := c.Get(CtxtUserIDKey)
	if !ok {
		err = ErrorUserNotLogin
		return
	}
	Uid, ok = uid.(int64)
	if !ok {
		err = ErrorUserNotLogin
		return
	}
	return
}*/

// PublishTask 发布任务的函数
// @Summary 发布任务接口
// @Description 发布任务接口,包含参数校验，逻辑处理和返回响应
// @Tags 用户相关接口
// @Accept application/json
// @Produce application/json
// @Param data body models.CreateTask true "data"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/publishTask [post]
func PublishTask(c *gin.Context) {
	//获取参数校验
	p := new(models.CreateTask)
	if err := c.ShouldBindWith(p, binding.JSON); err != nil {
		zap.L().Error("models.CreateTask BindJSON(p) failed", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeServerBusy)
			return
		}
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": removeTopStruct(errs.Translate(trans)),
		})
		return
	}
	//从c中获取到当前用户ID
	//Uid, err := getCurrentUserID(c)
	Uid, err := jwt.GetUserId(c)
	if err != nil {
		ResponseError(c, CodeNeedLogin)
		return
	}
	p.PublisherId = Uid
	fmt.Println()
	//创建任务
	if err := logic.CreateTask(p); err != nil {
		zap.L().Error("logic.CreateTask failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	go func() {
		err := logic.TimedShutdown(p)
		if err != nil {

		}
	}()

	//返回响应
	ResponseSuccess(c, nil)
}

// GetReceivePhone 查询接收人手机号的函数
// @Summary 查询接收人手机号接口
// @Description 查询接收人手机号的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamReceiveTask true "注册参数"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/getReceivePhone [post]
func GetReceivePhone(ctx *gin.Context) {
	p := new(models.ParamReceiveTask)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	phone, err := logic.GetReceivePhone(p.Id)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, phone)
}

// GetPublishPhone 查询发起人手机号的函数
// @Summary 查询发起人手机号接口
// @Description 查询发起人手机号的接口
// @Tags 任务相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamReceiveTask true "发起人"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/getPublishPhone [post]
func GetPublishPhone(ctx *gin.Context) {
	p := new(models.ParamReceiveTask)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	phone, err := logic.GetPublishPhone(p.Id)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, phone)
}

// GetPublishedTasks
// @Summary 查询所有已发布可以申领任务接口
// @Produce json
// @Description 查询所有已发布可以申领任务的接口
// @Tags 任务相关接口
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @router /api/v1/getPublishedTasks [get]
func GetPublishedTasks(ctx *gin.Context) {
	status := "发布" //待申领任务
	tasks, err := logic.GetTasksByStatus(status)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if tasks == nil || len(tasks) == 0 {
		ResponseError(ctx, CodeNotTask)
		return
	}
	ResponseSuccess(ctx, tasks)
}

// GetReceivedTasks
// @Summary 查询所有已接收的任务接口
// @Produce json
// @Description 查询所有已接收的任务接口
// @Tags 任务相关接口
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @router /api/v1/getReceivedTasks [get]
func GetReceivedTasks(ctx *gin.Context) {
	status := "已接收" //所有已接收的任务
	tasks, err := logic.GetTasksByStatus(status)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if tasks == nil || len(tasks) == 0 {
		ResponseError(ctx, CodeNotTask)
		return
	}
	ResponseSuccess(ctx, tasks)
}

// GetTasksFinish 函数用于接收前端传来的任务ID并调用修改任务状态的函数
// @Summary 完成任务
// @Description 接收前端传来的任务ID并调用修改任务状态的函数
// @Tags 任务相关接口
// @Accept json
// @Produce json
// @Param request body models.ParamSubmitVoucherTask true "任务请求参数"
// @Success 200 {object} ResponseData
// @Router /api/v1/getTasksFinish [post]
func GetTasksFinish(ctx *gin.Context) {
	// 声明一个 TaskRequest 结构体实例
	var request models.ParamSubmitVoucherTask //taskId
	Uid, err := jwt.GetUserId(ctx)
	// 解析 JSON 请求体
	if err := ctx.ShouldBindJSON(&request); err != nil {
		// 如果解析失败，返回错误信息给前端
		ResponseError(ctx, CodeServerBusy+1)
		return
	}
	userId, err := mysql.GetTaskPublisherID(request.Id)
	if Uid != userId {
		ResponseError(ctx, CodeServerBusy+2)
		return
	}

	err = logic.FinishTask(int64(request.Id))
	if err != nil {
		// 如果解析失败，返回错误信息给前端
		ResponseError(ctx, CodeServerBusy+3)
		return
	}
	ResponseSuccess(ctx, nil)
}

// GetTasksDown 函数用于接收前端传来的任务ID并调用下架任务的函数
// @Summary 下架任务
// @Description 接收前端传来的任务ID并调用下架任务的函数
// @Tags  任务相关接口
// @Accept json
// @Produce json
// @Param request body models.ParamSubmitVoucherTask true "任务请求参数"
// @Success 200 {object} ResponseData
// @Router /api/v1/getTasksDown [post]
func GetTasksDown(ctx *gin.Context) {
	// 声明一个 TaskRequest 结构体实例
	var request models.ParamSubmitVoucherTask
	Uid, err := jwt.GetUserId(ctx)
	// 解析 JSON 请求体
	if err := ctx.ShouldBindJSON(&request); err != nil {
		// 如果解析失败，返回错误信息给前端
		ResponseError(ctx, CodeServerBusy)
		return
	}

	status, err := mysql.GetTaskStatus(request.Id)
	fmt.Println(status)
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if status != "发布" && status != "已接收" {
		ResponseError(ctx, CodeDownFailed)
		return
	}

	userId, err := mysql.GetTaskPublisherID(request.Id)
	if Uid != userId {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	err = logic.DownTask(int64(request.Id))
	if err != nil {
		// 如果解析失败，返回错误信息给前端
		ResponseError(ctx, CodeServerBusy)
		return
	}

	ResponseSuccess(ctx, nil)
}

func Test1(ctx *gin.Context) {
	tasks, err := mysql.FindPendingTaskIDs()
	if err != nil {
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if tasks == nil || len(tasks) == 0 {
		ResponseError(ctx, CodeNotTask)
		return
	}
	ResponseSuccess(ctx, tasks)
}

//将任务状态为

// ReceiveTasks 接收任务的函数
// @Summary 接受任务函数
// @Description 接收任务接口,包含参数校验，逻辑处理和返回响应
// @Tags 用户相关接口
// @Accept application/json
// @Produce application/json
// @Param data body models.Tasks true "data"
// @Security ApiKeyAuth
// @Success 200 {object} ResponseData
// @Router /api/v1/receiveTasks [post]
//func ReceiveTasks(c *gin.Context) {
//	//获取参数校验
//	p := new(models.Tasks)
//	if err := c.ShouldBindJSON(p); err != nil {
//		zap.L().Debug("c.ShouldBindJSON(&p) error", zap.Any("err", err))
//		zap.L().Error("create task with in invalid param", zap.Error(err))
//		ResponseError(c, CodeInvalidParams)
//		return
//	}
//	//从c中获取到当前任务的id
//	tid := c.Param("id")
//	id, err := strconv.Atoi(tid)
//	/*
//		判断当前任务的状态是否是可接收的
//		0:发布
//		1:已接收
//		2:已完成
//		3:下架
//	*/
//	task, err := mysql.GetTask(id)
//	if task.TaskStatus != "发布" {
//		//该任务不能被接收，返回错误
//		ResponseError(c, CodeReceiveFailed)
//		return
//
//	}
//	//从c中获取到当前用户ID
//	Uid, err := getCurrentUserID(c)
//	if err != nil {
//		ResponseError(c, CodeNeedLogin)
//		return
//	}
//	//修改任务状态
//	logic.ReceiveTasks(id, Uid)
//	//返回响应
//}
